import com.ww.exercise.channel.actualcombat.producerconsumer.ChannelProcessor
import com.ww.exercise.channel.actualcombat.producerconsumer.Config
import com.ww.exercise.channel.actualcombat.producerconsumer.ShutdownResult
import kotlinx.coroutines.*
import java.util.concurrent.atomic.AtomicLong
import kotlin.time.Duration.Companion.seconds

/**
 * 终极压测工具 - 专注于计数器一致性
 */
class UltimateStressTester {

    /**
     * 终极测试：验证计数器永远不会出现负数
     */
    suspend fun testNoNegativeCounters(): UltimateTestResult {
        println("=== 终极测试：验证无负数计数器 ===")

        val processor = ChannelProcessor<String>(
            config = Config(
                channelCapacity = 500,
                consumerCount = 4,
                shutdownTimeout = 60.seconds
            )
        )

        val negativeCounters = AtomicLong(0)
        val totalChecks = AtomicLong(0)

        // 消费者
        processor.startConsumers { item ->
            // 随机处理时间，模拟真实场景
            delay((1..20).random().toLong())
        }

        val startTime = System.currentTimeMillis()

        // 监控协程：持续检查计数器一致性
        val monitorJob = GlobalScope.launch {
            while (isActive) {
                delay(50) // 每50ms检查一次
                val status = processor.getDetailedStatus()
                totalChecks.incrementAndGet()

                if (!status.countersConsistent) {
                    negativeCounters.incrementAndGet()
                    println("❌ 计数器不一致: produced=${status.produced}, consumed=${status.consumed}, " +
                            "calculated=${status.calculatedQueueSize}, diff=${status.consistencyDiff}")
                }

                if (System.currentTimeMillis() - startTime > 30000) { // 测试30秒
                    cancel()
                }
            }
        }

        // 生产者：大量快速生产
        val producerJob = GlobalScope.launch {
            var counter = 0
            while (System.currentTimeMillis() - startTime < 30000) {
                // 批量生产
                repeat(100) {
                    processor.tryProduce("Item-${counter++}")
                }
                delay(10) // 控制生产节奏
            }
            println("生产者完成")
        }

        producerJob.join()
        monitorJob.join()

        // 等待一段时间让消费者处理
        delay(5000)

        // 优雅关闭
        val shutdownResult = processor.shutdown()
        val duration = System.currentTimeMillis() - startTime

        val finalStatus = processor.getDetailedStatus()

        return UltimateTestResult(
            totalChecks = totalChecks.get(),
            negativeCounters = negativeCounters.get(),
            finalProduced = finalStatus.produced,
            finalConsumed = finalStatus.consumed,
            finalQueueSize = finalStatus.calculatedQueueSize,
            duration = duration,
            shutdownResult = shutdownResult,
            isPerfect = negativeCounters.get() == 0L
        )
    }

    /**
     * 边界条件测试：在关闭时大量生产
     */
    suspend fun testBoundaryConditions(): BoundaryTestResult {
        println("=== 边界条件测试：关闭时的大量生产 ===")

        val processor = ChannelProcessor<String>(
            config = Config(
                channelCapacity = 100,
                consumerCount = 2,
                shutdownTimeout = 10.seconds
            )
        )

        // 慢消费者
        processor.startConsumers { item ->
            delay(100)
        }

        val startTime = System.currentTimeMillis()
        val producedDuringShutdown = AtomicLong(0)

        // 快速生产者
        val producerJob = GlobalScope.launch {
            var counter = 0
            while (isActive) {
                if (processor.produce("Boundary-$counter")) {
                    counter++
                } else {
                    // 生产失败，可能是背压或关闭
                    break
                }
                delay(1)
            }
            println("生产者停止，共生产: $counter")
        }

        // 在运行一段时间后启动关闭
        delay(2000)

        println("=== 启动关闭，同时继续生产 ===")
        val shutdownJob = GlobalScope.launch {
            // 在关闭过程中继续尝试生产
            var shutdownCounter = 0
            while (isActive) {
                if (processor.tryProduce("DuringShutdown-$shutdownCounter")) {
                    producedDuringShutdown.incrementAndGet()
                }
                shutdownCounter++
                delay(1)
            }
        }

        // 等待一段时间后真正关闭
        delay(1000)
        val shutdownResult = processor.shutdown()

        producerJob.cancel()
        shutdownJob.cancel()

        val duration = System.currentTimeMillis() - startTime
        val finalStatus = processor.getDetailedStatus()

        return BoundaryTestResult(
            producedDuringShutdown = producedDuringShutdown.get(),
            finalProduced = finalStatus.produced,
            finalConsumed = finalStatus.consumed,
            finalQueueSize = finalStatus.calculatedQueueSize,
            duration = duration,
            shutdownResult = shutdownResult
        )
    }
}

/**
 * 终极测试结果
 */
data class UltimateTestResult(
    val totalChecks: Long,
    val negativeCounters: Long,
    val finalProduced: Long,
    val finalConsumed: Long,
    val finalQueueSize: Long,
    val duration: Long,
    val shutdownResult: ShutdownResult,
    val isPerfect: Boolean
) {
    val errorRate: Double get() = if (totalChecks > 0) negativeCounters.toDouble() / totalChecks else 0.0

    fun printReport() {
        println("\n" + "=".repeat(70))
        println("终极测试报告")
        println("=".repeat(70))
        println("总检查次数: $totalChecks")
        println("负数计数器次数: $negativeCounters")
        println("错误率: ${"%.6f".format(errorRate * 100)}%")
        println("最终状态: 生产=$finalProduced, 消费=$finalConsumed, 队列=$finalQueueSize")
        println("测试结果: ${if (isPerfect) "✅ 完美通过" else "❌ 存在异常"}")
        println("关闭结果: ${shutdownResult.message}")
        println("=".repeat(70))
    }
}

data class BoundaryTestResult(
    val producedDuringShutdown: Long,
    val finalProduced: Long,
    val finalConsumed: Long,
    val finalQueueSize: Long,
    val duration: Long,
    val shutdownResult: ShutdownResult
) {
    fun printReport() {
        println("\n" + "=".repeat(70))
        println("边界条件测试报告")
        println("=".repeat(70))
        println("关闭期间生产数量: $producedDuringShutdown")
        println("最终状态: 生产=$finalProduced, 消费=$finalConsumed, 队列=$finalQueueSize")
        println("关闭结果: ${shutdownResult.message}")
        println("=".repeat(70))
    }
}


/**
 * 运行终极测试套件
 */
suspend fun runUltimateTests() {
    val tester = UltimateStressTester()

    println("开始终极测试套件...")

    // 1. 运行无负数计数器测试
    println("\n>>> 运行无负数计数器测试 <<<")
    val ultimateResult = tester.testNoNegativeCounters()
    ultimateResult.printReport()

    delay(2000)

    // 2. 运行边界条件测试
    println("\n>>> 运行边界条件测试 <<<")
    val boundaryResult = tester.testBoundaryConditions()
    boundaryResult.printReport()

    // 总结
    println("\n" + "★".repeat(70))
    println("★                    终极测试总结                    ★")
    println("★".repeat(70))
    println("无负数计数器测试: ${if (ultimateResult.isPerfect) "✅ 通过" else "❌ 失败"}")
    println("边界条件测试: ${if (boundaryResult.shutdownResult.success) "✅ 通过" else "⚠️ 有警告"}")
    println("★".repeat(70))
}

suspend fun main() {
    runUltimateTests()
}